package edu.scau.web.payment;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.*;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import edu.scau.core.constants.AjaxResult;
import edu.scau.payment.config.AliPayConfig;
import edu.scau.payment.service.PaymentService;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.text.StringEscapeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

@RestController
@RequestMapping("/payment")
@Tag(name = "测试接口")
@Hidden
public class PaymenyController {
    @Autowired
    private AliPayConfig aliPayConfig;
    @Autowired
    private PaymentService paymentService;
    @Autowired
    private PayIndexController payIndexController;


    @GetMapping("/create")
    public AjaxResult create() throws AlipayApiException {
        AlipayClient alipayClient = new DefaultAlipayClient(this.getAlipayConfig());

        // 构造请求参数以调用接口
        AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
        String out_trade_no=UUID.randomUUID().toString();
        String total_amount="100";
        String subject="标题";
        String op_app_id=aliPayConfig.getAppId();
        String buyer_open_id="";
        request.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
                + "\"total_amount\":\""+ total_amount +"\","
                + "\"subject\":\""+ subject +"\","
                + "\"buyer_open_id\":\""+ buyer_open_id +"\","
                + "\"op_app_id\":\""+ op_app_id +"\"}");

        AlipayTradeCreateResponse response = alipayClient.execute(request);
        System.out.println(response.getBody());
        if (response.isSuccess()) {
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
            // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
            // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
            // System.out.println(diagnosisUrl);
        }
        return AjaxResult.success(response.getBody());
    }

    /**
     * 生成用户访问支付宝的跳转链接
     * alipay.trade.page.pay  AlipayTradePagePayRequest
     * @return TRADE_SUCCESS 成功创建+支付
     * @throws AlipayApiException
     */
    @GetMapping("/test")
    public AjaxResult test() throws AlipayApiException {
        // 初始化SDK
        AlipayClient alipayClient = new DefaultAlipayClient(this.getAlipayConfig());

        // 构造请求参数以调用接口
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        AlipayTradePagePayModel model = new AlipayTradePagePayModel();

    //商户订单号，商户网站订单系统中唯一订单号，必填
    String out_trade_no = UUID.randomUUID().toString();
    //付款金额，必填
    String total_amount = "1.1";
    //订单名称，必填
    String subject = "名称";
    //商品描述，可空
    String body = "boy";
    String timeout = "1m";


    request.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
            + "\"total_amount\":\""+ total_amount +"\","
            + "\"subject\":\""+ subject +"\","
            + "\"body\":\""+ body +"\","
            + "\"timeout_express\":\""+timeout+"\","
            + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        String returnUrl = "http://10.144.165.46:8081/payment/query?" ; // 支付成功后跳转到 query 接口
//        String notifyUrl = "https://yourdomain.com/payment/notify"; // 接收支付宝异步通知的接口

        request.setReturnUrl(returnUrl);
//        request.setNotifyUrl(notifyUrl);

        AlipayTradePagePayResponse response = alipayClient.pageExecute(request, "POST");
        // 如果需要返回GET请求，请使用
        // AlipayTradePagePayResponse response = alipayClient.pageExecute(request, "GET");
        String pageRedirectionData = response.getBody();
        String unescapedHtml = StringEscapeUtils.unescapeHtml4(pageRedirectionData);
        System.out.println(unescapedHtml);

        if (response.isSuccess()) {
            System.out.println("调用成功");
            return AjaxResult.success(unescapedHtml);
        } else {
            System.out.println("调用失败");
            return AjaxResult.error();
        }
    }




    /**
     * 回调查询交易成功订单的状态
     * @param params 回调查询参数
     * @return
     * @throws AlipayApiException
     */
    @GetMapping("/query")
    public AjaxResult query(@RequestParam Map<String, String> params) throws AlipayApiException, JsonProcessingException {
        System.out.println("收到支付宝回调参数：" + params);
        //不验签了
        // 2. 获取商户订单号
        String outTradeNo = params.get("out_trade_no");

        // 3. 查询订单状态
        AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        AlipayTradeQueryModel model = new AlipayTradeQueryModel();
        model.setOutTradeNo(outTradeNo);
        List<String> queryOptions = new ArrayList<>();
        queryOptions.add("trade_settle_info");
        model.setQueryOptions(queryOptions);
        request.setBizModel(model);
        //查询订单状态
        AlipayTradeQueryResponse response = alipayClient.execute(request);
        //解析
        Map<String,Object> resultMap=this.paseMap(response);
        if (response.isSuccess()) {
            System.out.println("query调用成功");
            if(Objects.equals((String) resultMap.get("trade_status"), "TRADE_SUCCESS")){
                Map<String,Object> data=new HashMap<>();
                data.put("交易ID",resultMap.get("trade_no"));
                data.put("交易时间",resultMap.get("send_pay_date"));
                return AjaxResult.success("订单支付成功",data);
            }
            if(Objects.equals((String) resultMap.get("trade_status"), "TRADE_CLOSED")){
                return AjaxResult.error("订单超时");
            }
        }
            System.out.println("query调用失败");
            return AjaxResult.error("sdk调用失败，请检查服务器");

    }

    @GetMapping("/queryManual")
    public AjaxResult queryManual(@RequestParam("out_trade_no")String out_trade_no) throws AlipayApiException, JsonProcessingException {

        AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        AlipayTradeQueryModel model = new AlipayTradeQueryModel();
        model.setOutTradeNo(out_trade_no);
        List<String> queryOptions = new ArrayList<>();
        queryOptions.add("trade_settle_info");
        model.setQueryOptions(queryOptions);
        request.setBizModel(model);
        //查询订单状态
        AlipayTradeQueryResponse response = alipayClient.execute(request);
        //解析
        Map<String,Object> resultMap=this.paseMap(response);
        System.out.println("172"+resultMap);
        if (response.isSuccess()) {
            System.out.println("query调用成功");
            if(Objects.equals((String) resultMap.get("trade_status"), "TRADE_SUCCESS")){
                Map<String,Object> data=new HashMap<>();
                data.put("交易状态","交易成功");
                data.put("交易ID",resultMap.get("trade_no"));
                data.put("交易时间",resultMap.get("send_pay_date"));
                return AjaxResult.success(data);
            }
            if(Objects.equals((String) resultMap.get("trade_status"), "TRADE_CLOSED")){
                Map<String,Object> data=new HashMap<>();
                data.put("交易状态","交易成功");
                data.put("交易ID",resultMap.get("trade_no"));
                data.put("交易金额",resultMap.get("total_amount"));
                data.put("交易时间",resultMap.get("send_pay_date"));
                return AjaxResult.success(data);
            }
        }
        System.out.println("query调用失败");
        return AjaxResult.error((String) resultMap.get("sub_msg"));

    }

    @GetMapping("/check")
    public void check(@RequestParam("out_trade_no") String out_trade_no) throws AlipayApiException {
        AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());

        // 构造请求参数以调用接口
        AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
        AlipayTradeCloseModel model = new AlipayTradeCloseModel();

        // 设置订单支付时传入的商户订单号
        model.setOutTradeNo(out_trade_no);

        // 设置商家操作员编号 id
        model.setOperatorId("YX01");

        request.setBizModel(model);
        // 第三方代调用模式下请设置app_auth_token
        // request.putOtherTextParam("app_auth_token", "<-- 请填写应用授权令牌 -->");

        AlipayTradeCloseResponse response = alipayClient.execute(request);
        System.out.println(response.getBody());

        if (response.isSuccess()) {
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
            // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
            // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
            // System.out.println(diagnosisUrl);
        }
    }



    /**
     * trade_status
     * WAIT_BUYER_PAY： 交易创建后，如果买家未付款，则进入 WAIT_BUYER_PAY 状态。
     * TRADE_SUCCESS： 买家完成支付后，交易进入 TRADE_SUCCESS 状态。
     * TRADE_FINISHED： 在一定时间后，交易自动进入 TRADE_FINISHED 状态（如果满足条件）。
     * TRADE_CLOSED： 如果买家未付款超时，或者商家主动关闭交易，则交易进入 TRADE_CLOSED 状态。
     * @param response
     * @return
     * @throws JsonProcessingException
     */
    public Map<String, Object>  paseMap(AlipayTradeQueryResponse response) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        Map<String, Object> responseMap = mapper.readValue(response.getBody(), Map.class);

        Map<String, Object> tradeQueryResponse = (Map<String, Object>) responseMap.get("alipay_trade_query_response");

        return tradeQueryResponse;
    }

    private AlipayConfig getAlipayConfig() {
        System.out.println("paC:187: "+aliPayConfig.toString());
        System.out.println("paC:187: "+aliPayConfig.getAppId());
        String privateKey  = aliPayConfig.getMerchantPrivateKey();
        String alipayPublicKey = aliPayConfig.getAlipayPublicKey();
        AlipayConfig newAlipayConfig = new AlipayConfig();
        newAlipayConfig.setServerUrl(aliPayConfig.getGatewayUrl());
        newAlipayConfig.setAppId(aliPayConfig.getAppId());
        System.out.println("paC:192: "+aliPayConfig.getAppId());
        newAlipayConfig.setPrivateKey(privateKey);
        newAlipayConfig.setFormat("json");
        newAlipayConfig.setAlipayPublicKey(alipayPublicKey);
        newAlipayConfig.setCharset("UTF-8");
        newAlipayConfig.setSignType("RSA2");
        return newAlipayConfig;
    }

}
